#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "map_file.h"
#include "mergesort_inversion_vector.h"

uint32_t *invert_mtf(uint32_t *seq, uint32_t *input_len, uint32_t num_syms);

void usage(const char *this_prog)
{
	fprintf(stderr, "Usage: %s <intsequencefile.mtf> <outputfile>\n", this_prog);
	fprintf(stderr, "Input and output are 32-bit integers\n");
	exit(1);
}

int main(int argc, char *argv[])
{
	int i;
	uint32_t num_syms = 0;

	if(argc < 3) {
		usage(argv[0]);
	}

	char *infilename = argv[1];
	ptr_range inmap = map_input_file(infilename);
	uint32_t *seq = (uint32_t *)inmap.sp;
	uint32_t len = (uint32_t *)inmap.ep - seq;

	fputs("Finding the largest symbol...", stdout);
	uint32_t highest = 0;
	for(i=0; i<len; i++) {
		if(seq[i] > highest) {
			highest = seq[i];
		}
	}
	num_syms = highest + 1;
	printf(" %d\n", highest);

	uint32_t *out_seq;
	out_seq = invert_mtf(seq, &len, num_syms);

	char *outfilename = argv[2];
	FILE *outfile = fopen(outfilename, "w");
	if(outfile == NULL) {
		perror(outfilename);
		fputs("Aborting\n", stderr);
		exit(1);
	}
	printf("Writing to %s...\n", outfilename);
	fwrite(out_seq, sizeof(uint32_t), len, outfile);
	fclose(outfile);

	return 0;
}

uint32_t *invert_mtf(uint32_t *seq, uint32_t *input_len, uint32_t num_syms)
{
	uint32_t i, len = *input_len;
	uint32_t *seq_copy = (uint32_t *)calloc(len + num_syms, sizeof(uint32_t));

	for(i=0; i<len; i++) {
		seq_copy[i] = num_syms - 1 - seq[i];
	}

	uint32_t *mtf = invert_reverse_inversion_vector(seq_copy, len + num_syms);
	for(i=0; i<len; i++) {
		if(mtf[i] < num_syms) {
			seq_copy[i] = num_syms - 1 - mtf[i];
		}
		else {
			seq_copy[i] = seq_copy[mtf[i] - num_syms];
		}
	}

	free(mtf);

	*input_len = len;
	return seq_copy;
}
